home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
hard
/
drivr
/
cyberx10.lha
/
CyberX10
/
Source
/
X10UpDown.c
< prev
Wrap
Text File
|
1992-11-06
|
14KB
|
599 lines
/*
* this contains the routines used to upload or download a program from/to
* the CP290's memory
*/
static struct TimerEvent_t {
UBYTE te_Mode;
UBYTE te_DOW;
UBYTE te_Hour;
UBYTE te_Minute;
UBYTE te_UnitMap[2];
UBYTE te_HouseCode;
UBYTE te_LevelFunction;
} TimerTable[128];
static int TimerTablePos;
static struct GraphicsData_t {
UBYTE gd_Graphic1;
UBYTE gd_Graphic2;
} GraphicTable[256];
static int GraphicsTablePos;
#define DOWNLOAD_TEMPLATE "TIMER/S,GRAPHICS/S,NORMAL/S,SECURITY/S,TODAY/S,TOMORROW/S,EVERYDAY/S,WEEKENDS/S,WEEKDAYS/S,MON/S,TUE/S,WED/S,THU/S,FRI/S,SAT/S,SUN/S,HOUR/K/N,MINUTE/K/N,HOUSECODE/K,ON/S,OFF/S,DIM/K/N,SPECIALS/M/A"
enum DownloadArgs {
ARG_TIMER,
ARG_GRAPHICS,
ARG_NORMAL,
ARG_SECURITY,
ARG_TODAY,
ARG_TOMORROW,
ARG_EVERYDAY,
ARG_WEEKENDS,
ARG_WEEKDAYS,
ARG_MON,
ARG_TUE,
ARG_WED,
ARG_THU,
ARG_FRI,
ARG_SAT,
ARG_SUN,
ARG_HOUR,
ARG_MINUTE,
ARG_HOUSECODE,
ARG_ON,
ARG_OFF,
ARG_DIM,
ARG_SPECIALS,
ARG_sizeof
};
/* prototypes for our private functions in this file */
static BOOL SendUploadRequest(BOOL RequestGraphics);
static UWORD ReadNextData(int DataLength, STRPTR Buffer);
/* parse a file and download it to the CP290 */
void X10Download(STRPTR filename)
{
BPTR fh;
int index;
UBYTE Buf[40];
struct RDArgs *RArgs1, *RArgs2;
STRPTR ArgArray[ARG_sizeof];
STRPTR LineBuf;
ULONG line;
STRPTR *Specials;
UWORD *uwordPtr;
int houseCode;
line = TimerTablePos = GraphicsTablePos = 0;
if (LineBuf = AllocVec(BIG_BUF_SIZE, 0)) {
if (fh = Open(filename, MODE_OLDFILE)) {
while (FGets(fh, LineBuf, BIG_BUF_SIZE_BASE)) {
line++;
if (LineBuf[0] == '#' || LineBuf[0] == '\n')
continue;
strcpy(&LineBuf[strlen(LineBuf)], "\n");
if (RArgs1 = AllocDosObject(DOS_RDARGS, TAG_DONE)) {
RArgs1->RDA_Source.CS_Buffer = LineBuf;
RArgs1->RDA_Source.CS_Length = strlen(LineBuf);
RArgs1->RDA_Source.CS_CurChr = 0L;
RArgs1->RDA_Flags |= RDAF_NOPROMPT;
memset(ArgArray, 0, sizeof(ArgArray));
RArgs2 = ReadArgs(DOWNLOAD_TEMPLATE, (LONG *) & ArgArray, RArgs1);
if (RArgs2) {
Specials = (STRPTR *) ArgArray[ARG_SPECIALS];
if (ArgArray[ARG_TIMER]) {
if (TimerTablePos < 128) {
if (ArgArray[ARG_SECURITY])
TimerTable[TimerTablePos].te_Mode = 9;
else if (ArgArray[ARG_TODAY])
TimerTable[TimerTablePos].te_Mode = 4;
else if (ArgArray[ARG_TOMORROW])
TimerTable[TimerTablePos].te_Mode = 2;
else
TimerTable[TimerTablePos].te_Mode = 8;
TimerTable[TimerTablePos].te_DOW = 0;
if (!ArgArray[ARG_TODAY] && !ArgArray[ARG_TOMORROW]) {
if (ArgArray[ARG_EVERYDAY])
TimerTable[TimerTablePos].te_DOW = 64 + 32 + 16 + 8 + 4 + 2 + 1;
else if (ArgArray[ARG_WEEKENDS])
TimerTable[TimerTablePos].te_DOW = 64 + 32;
else if (ArgArray[ARG_WEEKDAYS])
TimerTable[TimerTablePos].te_DOW = 16 + 8 + 4 + 2 + 1;
if (ArgArray[ARG_SUN])
TimerTable[TimerTablePos].te_DOW |= 64;
if (ArgArray[ARG_SAT])
TimerTable[TimerTablePos].te_DOW |= 32;
if (ArgArray[ARG_FRI])
TimerTable[TimerTablePos].te_DOW |= 16;
if (ArgArray[ARG_THU])
TimerTable[TimerTablePos].te_DOW |= 8;
if (ArgArray[ARG_WED])
TimerTable[TimerTablePos].te_DOW |= 4;
if (ArgArray[ARG_TUE])
TimerTable[TimerTablePos].te_DOW |= 2;
if (ArgArray[ARG_MON])
TimerTable[TimerTablePos].te_DOW |= 1;
}
if (ArgArray[ARG_HOUR])
TimerTable[TimerTablePos].te_Hour = *((LONG *) ArgArray[ARG_HOUR]);
else
TimerTable[TimerTablePos].te_Hour = (UBYTE) - 1;
if (ArgArray[ARG_MINUTE])
TimerTable[TimerTablePos].te_Minute = *((LONG *) ArgArray[ARG_MINUTE]);
else
TimerTable[TimerTablePos].te_Minute = (UBYTE) - 1;
houseCode = X10GetHC(*ArgArray[ARG_HOUSECODE]);
if (houseCode != -1)
TimerTable[TimerTablePos].te_HouseCode = HouseCode[houseCode];
if (ArgArray[ARG_ON])
TimerTable[TimerTablePos].te_LevelFunction = 2;
else if (ArgArray[ARG_DIM])
TimerTable[TimerTablePos].te_LevelFunction = 5 | ((*((LONG *) ArgArray[ARG_DIM]) - 1) << 4L);
else
TimerTable[TimerTablePos].te_LevelFunction = 3;
TimerTable[TimerTablePos].te_UnitMap[0] = 0;
TimerTable[TimerTablePos].te_UnitMap[1] = 0;
while (*Specials) {
index = (atol(*Specials++) - 1) & 0x0F;
if (index < 8)
TimerTable[TimerTablePos].te_UnitMap[0] |= 1L << (7 - index);
else
TimerTable[TimerTablePos].te_UnitMap[1] |= 1L << (7 - (index - 8));
}
if ((TimerTable[TimerTablePos].te_DOW || TimerTable[TimerTablePos].te_Mode == 4 || TimerTable[TimerTablePos].te_Mode == 2) &&
houseCode != -1 && (TimerTable[TimerTablePos].te_UnitMap[0] || TimerTable[TimerTablePos].te_UnitMap[1]) &&
TimerTable[TimerTablePos].te_Hour != -1 && TimerTable[TimerTablePos].te_Minute != -1)
TimerTablePos++;
else
ErrorMsg(MSG_PARSE_ERROR, line, filename);
}
else
ErrorMsg(MSG_TIMER_TABLE_FULL);
}
else if (ArgArray[ARG_GRAPHICS]) {
if (Specials[0] && Specials[1] && !Specials[2]) {
if (GraphicsTablePos < 256) {
GraphicTable[GraphicsTablePos].gd_Graphic1 = atol(Specials[0]);
GraphicTable[GraphicsTablePos++].gd_Graphic2 = atol(Specials[1]);
}
else
ErrorMsg(MSG_GRAPHICS_TABLE_FULL);
}
else
ErrorMsg(MSG_PARSE_ERROR, line, filename);
}
FreeArgs(RArgs2);
}
else
ErrorMsg(MSG_PARSE_ERROR, line, filename);
FreeDosObject(DOS_RDARGS, RArgs1);
}
else
ErrorMsg(MSG_NO_RDARGS);
}
Close(fh);
}
else
ErrorMsg(MSG_COULDNT_OPEN_FILE, filename);
FreeVec(LineBuf);
}
else
ErrorMsg(MSG_OUT_OF_MEMORY);
if (TimerTablePos)
for (index = 0; index < 128; index++) {
memset(Buf, 0xFF, 16);
Buf[16] = 3;
uwordPtr = (UWORD *) & Buf[17];
*uwordPtr = index * 8;
Buf[19] = Buf[17];
Buf[17] = Buf[18];
Buf[18] = Buf[19];
if (index < TimerTablePos)
CopyMem((APTR) & TimerTable[index], &Buf[19], 8);
else
memset(&Buf[19], 0, 8);
Buf[27] = Buf[19] + Buf[20] + Buf[21] + Buf[22] + Buf[23] + Buf[24] + Buf[25] + Buf[26];
ClearSerial();
SerWrite(Buf, 28);
if (!X10WaitForAck(FALSE)) {
ErrorMsg(MSG_CP290_ERROR_DOWNLOAD);
return;
}
}
if (GraphicsTablePos)
for (index = 0; index < 256; index++) {
memset(Buf, 0xFF, 16);
Buf[16] = 3;
uwordPtr = (UWORD *) & Buf[17];
*uwordPtr = index * 2 + 1024;
Buf[19] = Buf[17];
Buf[17] = Buf[18];
Buf[18] = Buf[19];
if (index < GraphicsTablePos)
CopyMem((APTR) & GraphicTable[index], &Buf[19], 2);
else
memset(&Buf[19], 0, 2);
Buf[21] = Buf[19] + Buf[20];
ClearSerial();
SerWrite(Buf, 22);
if (!X10WaitForAck(FALSE)) {
ErrorMsg(MSG_CP290_ERROR_DOWNLOAD);
return;
}
}
}
/* upload the information stored in the interface and write it to a file */
void X10Upload(STRPTR filename)
{
BPTR fh;
int index, index2;
UBYTE Buf[40];
UBYTE CheckSum;
UWORD raw;
STRPTR outText;
/* first try and download all the timer events */
if (SendUploadRequest(FALSE)) {
CheckSum = TimerTablePos = 0;
for (index = 0; index < 128; index++) {
raw = ReadNextData(8, (STRPTR) & TimerTable[TimerTablePos]);
if (raw == TIMEOUT) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_TIMEOUT));
return;
}
if (raw != EMPTY) {
CheckSum = (CheckSum + raw) & 0xFF;
TimerTablePos++;
}
}
raw = SerGetRawChar(2);
if (raw == TIMEOUT) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_TIMEOUT));
return;
}
if (raw != CheckSum) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_CHECKSUM));
return;
}
}
/* next try and download all the graphics data */
if (SendUploadRequest(TRUE)) {
CheckSum = GraphicsTablePos = 0;
for (index = 0; index < 256; index++) {
raw = ReadNextData(2, (STRPTR) & GraphicTable[GraphicsTablePos]);
if (raw == TIMEOUT) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_TIMEOUT));
return;
}
if (raw != EMPTY) {
CheckSum = (CheckSum + raw) & 0xFF;
GraphicsTablePos++;
}
}
raw = SerGetRawChar(2);
if (raw == TIMEOUT) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_TIMEOUT));
return;
}
if (raw != CheckSum) {
ErrorMsg(MSG_CP290_ERROR_READING, GetString(&LocaleInfo, MSG_CHECKSUM));
return;
}
}
/* now try and write the data to the specified file */
if (fh = Open(filename, MODE_NEWFILE)) {
if (FPuts(fh, GetString(&LocaleInfo, MSG_COMMENT_TIMER))) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
for (index = 0; index < TimerTablePos; index++) {
if (FPuts(fh, "timer ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
switch (TimerTable[index].te_Mode & 0x0F) {
case 8:
outText = "normal ";
break;
case 9:
outText = "security ";
break;
case 4:
outText = "today ";
break;
case 2:
outText = "tomorrow ";
break;
default:
outText = "";
break;
}
if (FPuts(fh, outText)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW == (64 + 32)) {
if (FPuts(fh, "weekends ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
else if (TimerTable[index].te_DOW == (16 + 8 + 4 + 2 + 1)) {
if (FPuts(fh, "weekdays ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
else if (TimerTable[index].te_DOW == (64 + 32 + 16 + 8 + 4 + 2 + 1)) {
if (FPuts(fh, "everyday ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
else {
if (TimerTable[index].te_DOW & 64)
if (FPuts(fh, "sun ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 1)
if (FPuts(fh, "mon ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 2)
if (FPuts(fh, "tue ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 4)
if (FPuts(fh, "wed ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 8)
if (FPuts(fh, "thu ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 16)
if (FPuts(fh, "fri ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
if (TimerTable[index].te_DOW & 32)
if (FPuts(fh, "sat ")) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
sprintf(Buf, "hour %02ld ", TimerTable[index].te_Hour);
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
sprintf(Buf, "minute %02ld ", TimerTable[index].te_Minute);
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
switch (TimerTable[index].te_LevelFunction & 0x0F) {
case 2:
outText = "on";
break;
case 3:
outText = "off";
break;
case 5:
sprintf(Buf, "dim %ld", (TimerTable[index].te_LevelFunction >> 4L) + 1);
outText = Buf;
break;
default:
outText = "";
break;
}
if (FPuts(fh, outText)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
for (index2 = 0; index2 < 16; index2++)
if (HouseCode[index2] == TimerTable[index].te_HouseCode) {
sprintf(Buf, " housecode %lc", index2 + 'A');
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
for (index2 = 0; index2 < 16; index2++)
if (TimerTable[index].te_UnitMap[index2 < 8 ? 0 : 1] & (1L << 7 - (index2 < 8 ? index2 : index2 - 8))) {
sprintf(Buf, " %ld", index2 + 1);
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
FPutC(fh, '\n');
} /* for TimerEvent loop */
sprintf(Buf, GetString(&LocaleInfo, MSG_COMMENT_GRAPHICS), TimerTablePos ? "\n" : "");
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
for (index = 0; index < GraphicsTablePos; index++) {
sprintf(Buf, "graphics %ld %ld\n", GraphicTable[index].gd_Graphic1, GraphicTable[index].gd_Graphic2);
if (FPuts(fh, Buf)) {
ErrorMsg(MSG_IO_ERROR, filename);
Close(fh);
return;
}
}
Close(fh);
}
else
ErrorMsg(MSG_CANT_CREATE_FILE, filename);
}
static BOOL SendUploadRequest(BOOL RequestGraphics)
{
UBYTE Buf[17];
UWORD raw;
int index;
memset(Buf, 0xFF, 16);
Buf[16] = RequestGraphics ? 6 : 5;
ClearSerial();
SerWrite(Buf, 17);
for (index = 0;;) {
raw = SerGetRawChar(15);
if (raw == TIMEOUT) {
ErrorMsg(MSG_CP290_ERROR_NO_RESPONSE);
return FALSE;
}
if (raw == 0xFF)
index++;
else if (index > 5)
return TRUE;
}
}
static UWORD ReadNextData(int DataLength, STRPTR Buffer)
{
UWORD raw;
UBYTE CheckSum;
int index;
raw = SerGetRawChar(2);
if (raw == TIMEOUT)
return TIMEOUT;
if (raw == 0xFF)
return EMPTY;
else { /* an event is stored here */
Buffer[0] = CheckSum = raw;
for (index = 1; index < DataLength; index++) {
raw = SerGetRawChar(2);
if (raw == TIMEOUT)
return TIMEOUT;
Buffer[index] = raw;
CheckSum += raw;
}
return (UWORD) CheckSum;
}
}